package jnpf.zc.controller;


import com.alibaba.fastjson.JSONObject;
import jnpf.fico.entity.ZcglCwZfjlEntity;
import jnpf.fico.service.ZcglCwZfjlService;
import jnpf.wx.SignEncryptDncryptSignChk;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * 子账簿到账通知接收接口
 * 用于接收民生银行子账簿到账结果与订单自动核销结果通知
 */
@RequestMapping("/api/example/payment")
@Slf4j
@RestController
public class SubAccountNotifyController {
    @Autowired
    private ZcglCwZfjlService zcglCwZfjlService;
    /**
     * 接收子账簿到账通知
     * 处理流程：接收密文 -> 解密 -> 验签 -> 解析通知内容 -> 业务处理 -> 返回SUCCESS
     */
    @PostMapping("/notice")
    public void receiveSubAccountNotify(@RequestBody String requestBody,
                                        HttpServletRequest request,
                                        HttpServletResponse response) throws IOException {
        try {
            // 1. 解析请求获取加密的context
            JSONObject notifyJson = JSONObject.parseObject(requestBody);
            String encryptedContext = notifyJson.getString("context");
            System.out.println("收到子账簿到账通知，加密内容：" + encryptedContext);

            if (encryptedContext == null || encryptedContext.isEmpty()) {
                throw new IllegalArgumentException("通知内容context为空");
            }

            // 2. 解密通知内容（使用工具类解密）
            String decryptedContext = SignEncryptDncryptSignChk.dncrypt(encryptedContext);
            System.out.println("--------------------------------------");
            System.out.println("解密后的通知内容：");
            System.out.println(decryptedContext);

            // 3. 验证签名（使用工具类验签）
            String signCheckResult = SignEncryptDncryptSignChk.signCheck(decryptedContext);
            System.out.println("--------------------------------------");
            System.out.println("签名验证结果：" + signCheckResult);

            if (!"SUCCESS".equals(signCheckResult)) {
                throw new SecurityException("通知签名验证失败");
            }

            // 4. 解析解密后的通知体
            JSONObject contextJson = JSONObject.parseObject(decryptedContext);
            String body = contextJson.getString("body");
            JSONObject notifyData = JSONObject.parseObject(body);
            System.out.println("--------------------------------------");
            System.out.println("通知详细内容：");

            // 5. 输出所有通知字段
            printNotifyFields(notifyData);

            // 6. 此处添加业务处理逻辑（如：更新订单状态、记录到账信息等）
            // processNotifyData(notifyData);

            // 7. 回复SUCCESS确认接收
            response.getWriter().write("SUCCESS");
        } catch (Exception e) {
            // 异常情况下也返回SUCCESS避免重复通知，实际应根据业务需求处理
            System.err.println("处理通知发生异常：" + e.getMessage());
            e.printStackTrace();
            response.getWriter().write("SUCCESS");
        }
    }

    /**
     * 打印通知中的所有字段
     */
    private void printNotifyFields(JSONObject notifyData) throws ParseException {

        log.info("商户号(platformId)：" + notifyData.getString("platformId"));
// 必输字段
        log.info("商户号(platformId)：" + notifyData.getString("platformId"));
        log.info("签约编码(merchantNo)：" + notifyData.getString("merchantNo"));
        log.info("渠道流水号(channelSerialNo)：" + notifyData.getString("channelSerialNo"));
        log.info("交易流水号(detSeq)：" + notifyData.getString("detSeq"));
        log.info("收款人名称(payeeAccName)：" + notifyData.getString("payeeAccName"));
        log.info("收款人账号(payeeAccNo)：" + notifyData.getString("payeeAccNo"));
        log.info("收款账户开户行行号(payeePartyId)：" + notifyData.getString("payeePartyId"));
        log.info("收款账户开户行名称(payeePartyName)：" + notifyData.getString("payeePartyName"));
        log.info("子账簿账号(accNo)：" + notifyData.getString("accNo"));
        log.info("交易金额(transAmount)：" + notifyData.getString("transAmount"));
        log.info("交易日期(tranDate)：" + notifyData.getString("tranDate"));
        log.info("交易时间(tranTime)：" + notifyData.getString("tranTime"));
        log.info("子账簿余额(balance)：" + notifyData.getString("balance"));

// 非必输字段
        log.info("借贷标识(dcFlag)：" + notifyData.getString("dcFlag"));
        log.info("付款人名称(draweeAccName)：" + notifyData.getString("draweeAccName"));
        log.info("付款人账号(draweeAccNo)：" + notifyData.getString("draweeAccNo"));
        log.info("付款账户类型(draweeAccType)：" + notifyData.getString("draweeAccType"));
        log.info("付款账户开户行行号(draweePartyId)：" + notifyData.getString("draweePartyId"));
        log.info("付款账户开户行名称(draweePartyName)：" + notifyData.getString("draweePartyName"));
        log.info("收款账户类型(payeeAccType)：" + notifyData.getString("payeeAccType"));
        log.info("币种(currencyCategory)：" + notifyData.getString("currencyCategory"));
        log.info("原转出流水号(originateChannelSerialNo)：" + notifyData.getString("originateChannelSerialNo"));
        log.info("交易状态(status)：" + notifyData.getString("status"));
        log.info("失败原因(failReason)：" + notifyData.getString("failReason"));
        log.info("交易类型(trnType)：" + notifyData.getString("trnType"));
        log.info("汇路(payPaymentPath)：" + notifyData.getString("payPaymentPath"));
        log.info("摘要(postscript)：" + notifyData.getString("postscript"));
        log.info("备注(summary)：" + notifyData.getString("summary"));
        log.info("扩展字段(inEtendData)：" + notifyData.getString("inEtendData"));

// 核销结果信息（可能为列表）
        log.info("核销结果信息(billList)：" + notifyData.getString("billList"));

        ZcglCwZfjlEntity zcglCwZfjlEntity = new ZcglCwZfjlEntity();
        zcglCwZfjlEntity.setPaymentAmount(new BigDecimal(notifyData.getString("transAmount")));
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        zcglCwZfjlEntity.setPaymentTime(sdf3.parse( notifyData.getString("tranTime")));
        zcglCwZfjlEntity.setPaymentAccount(notifyData.getString("draweeAccNo"));
        zcglCwZfjlEntity.setPaymentType(notifyData.getString("draweeAccType"));
        zcglCwZfjlEntity.setPaymentUser(notifyData.getString("draweeAccName"));
        zcglCwZfjlEntity.setStatus(notifyData.getString("status"));
        zcglCwZfjlService.save(zcglCwZfjlEntity);
    }

    /**
     * 业务处理方法（根据实际需求实现）
     */
    private void processNotifyData(JSONObject notifyData) {
        // 1. 记录通知日志
        // 2. 更新订单状态（如果有核销信息）
        // 3. 处理到账金额与子账簿余额
        // 4. 其他业务逻辑...
    }

}